<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
 
<html xmlns="http://www.w3.org/1999/xhtml">

<head>
    <title>Android应用程序窗口（Activity）的窗口对象（Window）的创建过程分析 - 老罗的Android之旅
        - 博客频道 - CSDN.NET</title>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    <meta name="description" content="在前文中，我们分析了Android应用程序窗口的运行上下文环境的创建过程。由此可知，每一个Activity组件都有一个关联的ContextImpl对象，同时，它还关联有一个Window对象，用来描述一个具体的应用程序窗口。由此又可知，Activity只不过是一个高度抽象的UI组件，它的具体UI实现其实是由其它的一系列对象来实现的。在本文中，我们就将详细分析Android应用程序窗口对象的创建过程。" />
    <script src="http://static.blog.csdn.net/scripts/jquery.js" type="text/javascript"></script>
    <script type="text/javascript" src="http://static.blog.csdn.net/scripts/ad.js?v=1.1"></script>
        <!--new top-->
               <link rel="stylesheet" href="http://static.csdn.net/public/common/toolbar/css/index.css">        <!--new top-->

    <link rel="Stylesheet" type="text/css" href="http://static.blog.csdn.net/skin/default/css/style.css?v=1.1" />
    <link id="RSSLink" title="RSS" type="application/rss+xml" rel="alternate" href="/Luoshengyang/rss/list" />
    <link rel="shortcut icon" href="/favicon.ico" />
    <link type="text/css" rel="stylesheet" href="http://static.blog.csdn.net/scripts/SyntaxHighlighter/styles/default.css" />
 

</head>
<body>
    
   
      <!--new top-->
    <script id="toolbar-tpl-scriptId" fixed="true" prod="blog" skin="black" src="http://static.csdn.net/public/common/toolbar/js/html.js" type="text/javascript"></script>
     <!--new top-->
    <div id="container">
        <div id="header">
    <div class="header">
        <div id="blog_title">
            <h2>
                <a href="http://blog.csdn.net/luoshengyang">老罗的Android之旅</a></h2>
            <h3>爱生活，爱Android</h3>
            <div class="clear">
            </div>
        </div>
        <div class="clear">
        </div>
    </div>
</div>
<div id="navigator">
    <div class="navigator_bg">
    </div>
    <div class="navigator">
        <ul>
                <li id="btnContents"><a href="http://blog.csdn.net/luoshengyang?viewmode=contents"><span onclick="_gaq.push(['_trackEvent','function', 'onclick', 'blog_articles_mulu'])">
                    <img src="http://static.blog.csdn.net/images/ico_list.gif">目录视图</span></a></li>
                <li id="btnView"><a href="http://blog.csdn.net/luoshengyang?viewmode=list"><span onclick="_gaq.push(['_trackEvent','function', 'onclick', 'blog_articles_zhaiyao'])">
                    <img src="http://static.blog.csdn.net/images/ico_summary.gif">摘要视图</span></a></li>
                <li id="btnRss"><a href="http://blog.csdn.net/luoshengyang/rss/list"><span onclick="_gaq.push(['_trackEvent','function', 'onclick', 'blog_articles_RSS'])">
                    <img src="http://static.blog.csdn.net/images/ico_rss.gif">订阅</span></a></li>
</ul>
    </div>
</div>
<script type="text/javascript">
    var username = "Luoshengyang";
    var _blogger = username;
    var blog_address = "http://blog.csdn.net/luoshengyang";
    var static_host = "http://static.blog.csdn.net";
    var currentUserName = "";
</script>

        <div id="body">
            <div id="main">
                <div class="main">
<div class="notice tracking-ad" data-mod='popu_3' > 


<a href="http://hero.csdn.net/Question/Details?ID=351&ExamID=346" target="_blank"><font color=blue>英雄会第四届在线编程大赛·线上初赛：带通配符的数
</font></a>

&nbsp;&nbsp;&nbsp;&nbsp;


<a href="http://bbs.csdn.net/topics/390724670"target="_blank">
<font color=red>CSDN社区“三八节”特别活动</font></a>
&nbsp;&nbsp;&nbsp;&nbsp;


<a href="http://www.csdn.net/article/2014-03-06/2818653"target="_blank">
<font color=blue>开发者职业生涯调查之未来</font></a>




</div>                    <link href="http://static.blog.csdn.net/css/comment1.css" type="text/css" rel="stylesheet" />
<link href="http://static.blog.csdn.net/css/style1.css" type="text/css" rel="stylesheet" />
<div id="article_details" class="details">
    <div class="article_title">
    <span class="ico ico_type_Original"></span>
    <h1>
        <span class="link_title"><a href="/luoshengyang/article/details/8223770">
        Android应用程序窗口（Activity）的窗口对象（Window）的创建过程分析
        </a></span>
    </h1>
</div>

    <div class="article_manage">
        <span class="link_categories">
        分类：
            <a href="/Luoshengyang/article/category/838604">Android</a> 
        </span>
    <span class="link_postdate">2012-12-03 00:55</span>
    <span class="link_view" title="阅读次数">20688人阅读</span>
    <span class="link_comments" title="评论次数"><a href="#comments" onclick="_gaq.push(['_trackEvent','function', 'onclick', 'blog_articles_pinglun'])">评论</a>(21)</span>
    <span class="link_collect"><a href="javascript:void(0);" onclick="javascript:_gaq.push(['_trackEvent','function', 'onclick', 'blog_articles_shoucang']);collectArticle('Android应用程序窗口（Activity）的窗口对象（Window）的创建过程分析','8223770');return false;" title="收藏">收藏</a></span>
    <span class="link_report"><a href="#report"  onclick="javascript:_gaq.push(['_trackEvent','function', 'onclick', 'blog_articles_jubao']);report(8223770,2);return false;" title="举报">举报</a></span>
    
</div>
<div class="tag2box"><a href='http://www.csdn.net/tag/Activity' target=_blank onclick="_gaq.push(['_trackEvent','function', 'onclick', 'blog_articles_tag']);">Activity</a><a href='http://www.csdn.net/tag/android' target=_blank onclick="_gaq.push(['_trackEvent','function', 'onclick', 'blog_articles_tag']);">android</a><a href='http://www.csdn.net/tag/PhoneWindow' target=_blank onclick="_gaq.push(['_trackEvent','function', 'onclick', 'blog_articles_tag']);">PhoneWindow</a><a href='http://www.csdn.net/tag/window' target=_blank onclick="_gaq.push(['_trackEvent','function', 'onclick', 'blog_articles_tag']);">window</a><a href='http://www.csdn.net/tag/%e5%ba%94%e7%94%a8%e7%a8%8b%e5%ba%8f%e7%aa%97%e5%8f%a3' target=_blank onclick="_gaq.push(['_trackEvent','function', 'onclick', 'blog_articles_tag']);">应用程序窗口</a></div>

    
<div id="article_content" class="article_content">
<p><span style="color:black;">&nbsp;&nbsp; &nbsp; &nbsp; 在前文中，我们分析了</span><span style="color:black;">Android</span><span style="color:black;">应用程序窗口的运行上下文环境的创建过程。由此可知，每一个</span><span style="color:black;">Activity</span><span style="color:black;">组件都有一个关联的</span><span style="color:black;">ContextImpl</span><span style="color:black;">对象，同时，它还关联有一个</span><span style="color:black;">Window</span><span style="color:black;">对象，用来描述一个具体的应用程序窗口。由此又可知，</span><span style="color:black;">Activity</span><span style="color:black;">只不过是一个高度抽象的</span><span style="color:black;">UI</span><span style="color:black;">组件，它的具体</span><span style="color:black;">UI</span><span style="color:black;">实现其实是由其它的一系列对象来实现的。在本文中，我们就将详细分析</span><span style="color:black;">Android</span><span style="color:black;">应用程序窗口对象的创建过程。</span></p><p><span style="color:black;">&nbsp;&nbsp; &nbsp; &nbsp; 从前面<a target=_blank target="_blank" href="http://blog.csdn.net/luoshengyang/article/details/8170307">Android应用程序窗口（Activity）实现框架简要介绍和学习计划</a>一文可以知道，在PHONE平台上，与Activity组件所关联的窗口对象的实际类型为PhoneWindow，后者是从Window类继承下来的。Activity、Window和PhoneWindow三个类的关系可以参考<a target=_blank target="_blank" href="http://blog.csdn.net/luoshengyang/article/details/8170307">Android应用程序窗口（Activity）实现框架简要介绍和学习计划</a>一文中的图3和图5。为了方便接下来描述类型为PhoneWindow的应用程序窗口的创建过程，我们将这两个图拿过来，如以下的图1和图2所示：</span></p><p style="text-align: center;"><span style="color: black; "><img src="http://img.my.csdn.net/uploads/201211/29/1354201827_9391.jpg" alt="" /><br /></span></p><p style="text-align: center;"><span style="color: black; ">图1 Activity和Window的类关系图</span></p><p style="text-align: center;"><span style="color: black; "><img src="http://img.my.csdn.net/uploads/201211/13/1352736693_6736.jpg" alt="" /><br /></span></p><p style="text-align: center;">图2 Window和PhoneWindow的类关系图</p><p><span style="color:black;">&nbsp;&nbsp; &nbsp; &nbsp; 上述两个图中所涉及到的类的描述可以参考<a target=_blank target="_blank" href="http://blog.csdn.net/luoshengyang/article/details/8170307">Android应用程序窗口（Activity）实现框架简要介绍和学习计划</a>一文，本文主要从<span style="color: black; ">Android</span><span style="color: black; ">应用程序窗口的创建过程来</span>理解Activity、Window和PhoneWindow三个类的关系。</span></p><p><span style="color:black;">&nbsp;&nbsp; &nbsp; &nbsp; 从<a target=_blank target="_blank" href="http://blog.csdn.net/luoshengyang/article/details/8201936">Android应用程序窗口（Activity）的运行上下文环境（Context）的创建过程分析</a>一文又可以知道，与Activity组件所关联的一个PhoneWindow对象是从Activity类的成员函数attach中创建的，如图3所示：</span></p><p style="text-align: center;"><span style="color:black;"><img width="691" src="http://img.my.csdn.net/uploads/201211/26/1353944092_1763.jpg" alt="" /><br /></span></p><p style="text-align: center;"><span style="color:black;">图3 Android应用程序窗口的创建过程</span></p><p><span style="color:black;">&nbsp;&nbsp; &nbsp; &nbsp; 这个过程可以分为9个步骤，接下来我们就详细分析每一个步骤。</span></p><p><span style="color:black;">&nbsp;&nbsp; &nbsp; &nbsp; Step 1. Activity.attach</span></p><p><span style="color:black;"></span></p><pre code_snippet_id="129045" snippet_file_name="blog_20131226_1_9524966"  code_snippet_id="129045" snippet_file_name="blog_20131226_1_9524966" name="code" class="java">public class Activity extends ContextThemeWrapper  
        implements LayoutInflater.Factory,  
        Window.Callback, KeyEvent.Callback,  
        OnCreateContextMenuListener, ComponentCallbacks {  
    ......   
  
    private Window mWindow;   
    ......  
  
    final void attach(Context context, ActivityThread aThread,  
            Instrumentation instr, IBinder token, int ident,  
            Application application, Intent intent, ActivityInfo info,  
            CharSequence title, Activity parent, String id,  
            Object lastNonConfigurationInstance,  
            HashMap&lt;String,Object&gt; lastNonConfigurationChildInstances,  
            Configuration config) {  
        ......  
  
        mWindow = PolicyManager.makeNewWindow(this);  
        mWindow.setCallback(this);  
        if (info.softInputMode != WindowManager.LayoutParams.SOFT_INPUT_STATE_UNSPECIFIED) {  
            mWindow.setSoftInputMode(info.softInputMode);  
        }  
        ......  
  
        mWindow.setWindowManager(null, mToken, mComponent.flattenToString());  
        ......  
    
    }  
  
    ......  
}  </pre><p>&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;这个函数定义在文件frameworks/base/core/java/android/app/Activity.java中。</p><p>&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;在前面<a target=_blank target="_blank" href="http://blog.csdn.net/luoshengyang/article/details/8201936">Android应用程序窗口（Activity）的运行上下文环境（Context）的创建过程分析</a>一文中，我们已经分析过这个函数的实现了，这里我们只关注与应用程序窗口创建相关的代码。</p><p>&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;函数首先调用PolicyManager类的静态成员函数makeNewWindow来创建一个类型为PhoneWindow的应用程序窗口，并且保存在Activity类的成员变量mWindow中。有了这个类型为PhoneWindow的应用程序窗口，函数接下来还会调用它的成员函数setCallback、setSoftInputMode和setWindowManager来设置窗口回调接口、软键盘输入区域的显示模式和本地窗口管理器。</p><p>&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;PhoneWindow类的成员函数setCallback、setSoftInputMode和setWindowManager都是从父类Window继承下来的，因此，接下来我们就继续分析PolicyManager类的静态成员函数makeNewWindow，以及Window类的成员函数setCallback、setSoftInputMode和setWindowManager的实现。</p><p>&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;Step 2.&nbsp;PolicyManager.makeNewWindow</p><p></p><pre code_snippet_id="129045" snippet_file_name="blog_20131226_2_397802"  code_snippet_id="129045" snippet_file_name="blog_20131226_2_397802" name="code" class="java">public final class PolicyManager {
    private static final String POLICY_IMPL_CLASS_NAME =
        &quot;com.android.internal.policy.impl.Policy&quot;;

    private static final IPolicy sPolicy;

    static {
        // Pull in the actual implementation of the policy at run-time
        try {
            Class policyClass = Class.forName(POLICY_IMPL_CLASS_NAME);
            sPolicy = (IPolicy)policyClass.newInstance();
        } catch (ClassNotFoundException ex) {
            throw new RuntimeException(
                    POLICY_IMPL_CLASS_NAME + &quot; could not be loaded&quot;, ex);
        } catch (InstantiationException ex) {
            throw new RuntimeException(
                    POLICY_IMPL_CLASS_NAME + &quot; could not be instantiated&quot;, ex);
        } catch (IllegalAccessException ex) {
            throw new RuntimeException(
                    POLICY_IMPL_CLASS_NAME + &quot; could not be instantiated&quot;, ex);
        }
    }

    ......

    // The static methods to spawn new policy-specific objects
    public static Window makeNewWindow(Context context) {
        return sPolicy.makeNewWindow(context);
    }

    ......
}</pre>&nbsp;&nbsp; &nbsp; &nbsp; 这个函数定义在文件frameworks/base/core/java/com/android/internal/policy/PolicyManager.java中。<p></p><p>&nbsp;&nbsp; &nbsp; &nbsp; PolicyManager是一个窗口管理策略类，它在第一次被使用的时候，就会创建一个Policy类实例，并且保存在静态成员变量sPolicy中，以后PolicyManager类的窗口管理策略就是通过这个Policy类实例来实现的，例如，PolicyManager类的静态成员函数makeNewWindow就是通过调用这个Policy类实例的成员函数makeNewWindow来创建一个具体的应用程序窗口的。</p><p>&nbsp;&nbsp; &nbsp; &nbsp; 接下来，我们就继续分析Policy类的成员函数makeNewWindow的实现。</p><p>&nbsp;&nbsp; &nbsp; &nbsp; Step 3.&nbsp;Policy.makeNewWindow</p><p></p><pre code_snippet_id="129045" snippet_file_name="blog_20131226_3_4476220"  code_snippet_id="129045" snippet_file_name="blog_20131226_3_4476220" name="code" class="java">public class Policy implements IPolicy {
    ......

    public PhoneWindow makeNewWindow(Context context) {
        return new PhoneWindow(context);
    }
 
    ......
}</pre>&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;这个函数定义在文件frameworks/base/policy/src/com/android/internal/policy/impl/Policy.java中。<p></p><p>&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;Policy类的成员函数makeNewWindow的实现很简单，它只是创建了一个PhoneWindow对象，然后返回给调用者。</p><p>&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;接下来，我们就继续分析PhoneWindow类的构造函数的实现，以便可以了解一个类型为PhoneWindow的应用程序窗口的创建过程。</p><p>&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;Step 4. new PhoneWindow</p><p></p><pre code_snippet_id="129045" snippet_file_name="blog_20131226_4_157822"  code_snippet_id="129045" snippet_file_name="blog_20131226_4_157822" name="code" class="java">public class PhoneWindow extends Window implements MenuBuilder.Callback {
    ......

    // This is the top-level view of the window, containing the window decor.
    private DecorView mDecor;

    // This is the view in which the window contents are placed. It is either
    // mDecor itself, or a child of mDecor where the contents go.
    private ViewGroup mContentParent;
    ......

    private LayoutInflater mLayoutInflater;
    ......

    public PhoneWindow(Context context) {
        super(context);
        mLayoutInflater = LayoutInflater.from(context);
    }

    ......
}</pre>&nbsp;&nbsp; &nbsp; &nbsp; 这个函数定义在文件frameworks/base/policy/src/com/android/internal/policy/impl/PhoneWindow.java中。<p></p><p>&nbsp;&nbsp; &nbsp; &nbsp;&nbsp;PhoneWindow类的构造函数很简单，它首先调用父类Window的构造函数来执行一些初始化操作，接着再调用LayoutInflater的静态成员函数from创建一个LayoutInflater实例，并且保存在成员变量mLayoutInflater中。这样，PhoneWindow类以后就可以通过成员变量mLayoutInflater来创建应用程序窗口的视图，这个视图使用类型为DecorView的成员变量mDecor来描述。PhoneWindow类还有另外一个类型为ViewGroup的成员变量mContentParent，用来描述一个视图容器，这个容器存放的就是成员变量mDecor所描述的视图的内容，不过这个容器也有可能指向的是mDecor本身。在后面的文章中，我们再详细分析类型为PhoneWindow的应用程序窗口的视图的创建过程。</p><p>&nbsp;&nbsp; &nbsp; &nbsp;Window的构造函数定义在文件frameworks/base/core/java/android/view/Window.java中，它的实现很简单，只是初始化了其成员变量mContext，如下所示：</p><p></p><pre code_snippet_id="129045" snippet_file_name="blog_20131226_5_2459116"  code_snippet_id="129045" snippet_file_name="blog_20131226_5_2459116" name="code" class="java">public abstract class Window {
    ......

    private final Context mContext;
    ......

    public Window(Context context) {
        mContext = context;
    }
  
    ......
}</pre>&nbsp;&nbsp; &nbsp; &nbsp; 从前面的调用过程可以知道，参数context描述的是正在启动的Activity组件，将它保存在Window类的成员变量mContext之后，Window类就可以通过它来访问与Activity组件相关的资源了。<p></p><p>&nbsp;&nbsp; &nbsp; &nbsp; 这一步执行完成之后，回到前面的Step 1中，即Activity类的成员函数attach中，接下来就会继续调用前面所创建的PhoneWindow对象从父类Window继承下来的成员函数setCallback来设置窗口回调接口，因此，接下来我们就继续分析Window类的成员函数setCallback的实现。</p><p>&nbsp;&nbsp; &nbsp; &nbsp; Step 5. Window.setCallback</p><p></p><pre code_snippet_id="129045" snippet_file_name="blog_20131226_6_6188870"  code_snippet_id="129045" snippet_file_name="blog_20131226_6_6188870" name="code" class="java">public abstract class Window {
    ......

    private Callback mCallback;
    ......

    /**
     * Set the Callback interface for this window, used to intercept key
     * events and other dynamic operations in the window.
     *
     * @param callback The desired Callback interface.
     */
    public void setCallback(Callback callback) {
        mCallback = callback;
    }
  
    ......
}</pre><p>&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;这个函数定义在文件frameworks/base/core/java/android/view/Window.java中。</p><p>&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;正在启动的Activity组件会将它所实现的一个Callback接口设置到与它所关联的一个PhoneWindow对象的父类Window的成员变量mCallback中去，这样当这个PhoneWindow对象接收到系统给它分发的IO输入事件，例如，键盘和触摸屏事件，转发给与它所关联的Activity组件处理，这一点可以参考前面<a target=_blank target="_blank" href="http://blog.csdn.net/luoshengyang/article/details/6882903">Android应用程序键盘（Keyboard）消息处理机制分析</a>一文。</p><p>&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;这一步执行完成之后，回到前面的Step 1中，即Activity类的成员函数attach中，接下来就会继续调用前面所创建的PhoneWindow对象从父类Window继承下来的成员函数setSoftInputMode来设置应用程序窗口的软键盘输入区域的显示模式，因此，接下来我们就继续分析Window类的成员函数setSoftInputMode的实现。</p><p>&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;Step 6.&nbsp;Window.setSoftInputMode</p><pre code_snippet_id="129045" snippet_file_name="blog_20131226_7_8282421"  code_snippet_id="129045" snippet_file_name="blog_20131226_7_8282421" name="code" class="java">public abstract class Window {
    ......

    private boolean mHasSoftInputMode = false;
    ......

    public void setSoftInputMode(int mode) {
        final WindowManager.LayoutParams attrs = getAttributes();
        if (mode != WindowManager.LayoutParams.SOFT_INPUT_STATE_UNSPECIFIED) {
            attrs.softInputMode = mode;
            mHasSoftInputMode = true;
        } else {
            mHasSoftInputMode = false;
        }
        if (mCallback != null) {
            mCallback.onWindowAttributesChanged(attrs);
        }
    }

    ......
}</pre><p>&nbsp;&nbsp; &nbsp; &nbsp; 这个函数定义在文件frameworks/base/core/java/android/view/Window.java中。</p><p>&nbsp;&nbsp; &nbsp; &nbsp; 参数mode有SOFT_INPUT_STATE_UNSPECIFIED、SOFT_INPUT_STATE_UNCHANGED、SOFT_INPUT_STATE_HIDDEN、SOFT_INPUT_STATE_ALWAYS_HIDDEN、SOFT_INPUT_STATE_VISIBLE和SOFT_INPUT_STATE_ALWAYS_VISIBLE一共六个取值，用来描述窗口的软键盘输入区域的显示模式，它们的含义如下所示：</p><p>&nbsp;&nbsp; &nbsp; &nbsp;1.&nbsp;<strong>SOFT_INPUT_STATE_UNSPECIFIED</strong>：没有指定软键盘输入区域的显示状态。</p><p>&nbsp;&nbsp; &nbsp; &nbsp;2.&nbsp;<strong>SOFT_INPUT_STATE_UNCHANGED</strong>：不要改变软键盘输入区域的显示状态。</p><p>&nbsp;&nbsp; &nbsp; &nbsp;3.&nbsp;<strong>SOFT_INPUT_STATE_HIDDEN</strong>：在合适的时候隐藏软键盘输入区域，例如，当用户导航到当前窗口时。</p><p>&nbsp;&nbsp; &nbsp; &nbsp;4.&nbsp;<strong>SOFT_INPUT_STATE_ALWAYS_HIDDEN</strong>：当窗口获得焦点时，总是隐藏软键盘输入区域。</p><p>&nbsp;&nbsp; &nbsp; &nbsp;5.&nbsp;<strong>SOFT_INPUT_STATE_VISIBLE</strong>：在合适的时候显示软键盘输入区域，例如，当用户导航到当前窗口时。</p><p>&nbsp;&nbsp; &nbsp; &nbsp;6.&nbsp;<strong>SOFT_INPUT_STATE_ALWAYS_VISIBLE</strong>：当窗口获得焦点时，总是显示软键盘输入区域。</p><p>&nbsp;&nbsp; &nbsp; &nbsp;当参数mode的值不等于SOFT_INPUT_STATE_UNSPECIFIED时，就表示当前窗口被指定软键盘输入区域的显示模式，这时候Window类的成员函数setSoftInputMode就会将成员变量mHasSoftInputMode的值设置为true，并且将这个显示模式保存在用来描述窗口布局属性的一个WindowManager.LayoutParams对象的成员变量softInputMode中，否则的话，就会将成员变量mHasSoftInputMode的值设置为false。</p><p>&nbsp;&nbsp; &nbsp; &nbsp;设置完成窗口的软键盘输入区域的显示模式之后，如果Window类的成员变量mCallback指向了一个窗口回调接口，那么Window类的成员函数setSoftInputMode还会调用它的成员函数onWindowAttributesChanged来通知与窗口所关联的Activity组件，它的窗口布局属性发生了变化。</p><p>&nbsp;&nbsp; &nbsp; &nbsp; 这一步执行完成之后，回到前面的Step 1中，即Activity类的成员函数attach中，接下来就会继续调用前面所创建的PhoneWindow对象从父类Window继承下来的成员函数setWindowManager来设置应用程序窗口的本地窗口管理器，因此，接下来我们就继续分析Window类的成员函数setWindowManager的实现。</p><p>&nbsp;&nbsp; &nbsp; &nbsp; Step 7.&nbsp;Window.setWindowManager</p><p></p><pre code_snippet_id="129045" snippet_file_name="blog_20131226_8_3964022"  code_snippet_id="129045" snippet_file_name="blog_20131226_8_3964022" name="code" class="java">public abstract class Window {
    ......

    private WindowManager mWindowManager;
    private IBinder mAppToken;
    private String mAppName;
    ......

    public void setWindowManager(WindowManager wm,
            IBinder appToken, String appName) {
        mAppToken = appToken;
        mAppName = appName;
        if (wm == null) {
            wm = WindowManagerImpl.getDefault();
        }
        mWindowManager = new LocalWindowManager(wm);
    }

    ......
}</pre>&nbsp;&nbsp; &nbsp; &nbsp;&nbsp;这个函数定义在文件frameworks/base/core/java/android/view/Window.java中。<p></p><p>&nbsp;&nbsp; &nbsp; &nbsp; 参数appToken用来描述当前正在处理的窗口是与哪一个Activity组件关联的，它是一个Binder代理对象，引用了在ActivityManagerService这一侧所创建的一个类型为ActivityRecord的Binder本地对象。从前面<a target=_blank target="_blank" href="http://blog.csdn.net/luoshengyang/article/details/6685853">Android应用程序的Activity启动过程简要介绍和学习计划</a>一系列文章可以知道，每一个启动起来了的Activity组件在ActivityManagerService这一侧，都有一个对应的ActivityRecord对象，用来描述该Activity组件的运行状态。这个Binder代理对象会被保存在Window类的成员变量mAppToken中，这样当前正在处理的窗口就可以知道与它所关联的Activity组件是什么。</p><p>&nbsp;&nbsp; &nbsp; &nbsp; 参数appName用来描述当前正在处理的窗口所关联的Activity组件的名称，这个名称会被保存在Window类的成员变量mAppName中。</p><p>&nbsp;&nbsp; &nbsp; &nbsp; 参数wm用来描述一个窗口管理器。从前面的调用过程可以知道， 这里传进来的参数wm的值等于null，因此，函数首先会调用WindowManagerImpl类的静态成员函数getDefault来获得一个默认的窗口管理器。有了这个窗口管理器之后，函数接着再使用它来创建一个本地窗口管理器，即一个LocalWindowManager对象，用来维护当前正在处理的应用程序窗口。</p><p>&nbsp;&nbsp; &nbsp; &nbsp; 接下来，我们首先分析WindowManagerImpl类的静态成员函数getDefault的实现，接着再分析本地窗口管理器的创建过程，即LocalWindowManager类的构造函数的实现。</p><p>&nbsp;&nbsp; &nbsp; &nbsp; Step 8.&nbsp;WindowManagerImpl.getDefault</p><p></p><pre code_snippet_id="129045" snippet_file_name="blog_20131226_9_6298336"  code_snippet_id="129045" snippet_file_name="blog_20131226_9_6298336" name="code" class="java">public class WindowManagerImpl implements WindowManager {
    ......

    public static WindowManagerImpl getDefault()
    {
        return mWindowManager;
    }
 
    ......

    private static WindowManagerImpl mWindowManager = new WindowManagerImpl();
}</pre>&nbsp;&nbsp; &nbsp; &nbsp; 这个函数定义在文件frameworks/base/core/java/android/view/WindowManagerImpl.java中。<p></p><p>&nbsp;&nbsp; &nbsp; &nbsp;&nbsp;WindowManagerImpl类的静态成员函数getDefault的实现很简单，它只是将静态成员变量mWindowManager所指向的一个WindowManagerImpl对象返回给调用者，这个WindowManagerImpl对象实现了WindowManager接口，因此，它就可以用来管理应用程序窗口。</p><p>&nbsp;&nbsp; &nbsp; &nbsp;这一步执行完成之后，回到前面的Step 7中，即Window类的成员函数setWindowManager中，接下来就会使用前面所获得一个WindowManagerImpl对象来创建一个本地窗口管理器，即一个LocalWindowManager对象。</p><p>&nbsp;&nbsp; &nbsp; &nbsp;Step 9. new&nbsp;LocalWindowManager</p><p></p><pre code_snippet_id="129045" snippet_file_name="blog_20131226_10_900143"  code_snippet_id="129045" snippet_file_name="blog_20131226_10_900143" name="code" class="java">public abstract class Window {
    ......

    private final Context mContext;
    ......

    private class LocalWindowManager implements WindowManager {
        LocalWindowManager(WindowManager wm) {
            mWindowManager = wm;
            mDefaultDisplay = mContext.getResources().getDefaultDisplay(
                    mWindowManager.getDefaultDisplay());
        }

        ......

        private final WindowManager mWindowManager;

        private final Display mDefaultDisplay;
    }

    ......
}</pre>&nbsp;&nbsp; &nbsp; &nbsp; 这个函数定义在文件frameworks/base/core/java/android/view/Window.java中。<p></p><p>&nbsp;&nbsp; &nbsp; &nbsp;&nbsp;LocalWindowManager类的构造函数首先将参数wm所描述的一个WindowManagerImpl对象保存它的成员变量mWindowManager中，这样以后就将窗口管理工作交给它来处理。</p><p>&nbsp;&nbsp; &nbsp; &nbsp;&nbsp;LocalWindowManager类的构造函数接着又通过成员变量mWindowManager所描述的一个WindowManagerImpl对象的成员函数getDefaultDisplay来获得一个Display对象，用来描述系统屏幕属性。</p><p>&nbsp;&nbsp; &nbsp; &nbsp; 由于前面所获得的Display对象描述的是全局的屏幕属性，而当前正在处理的窗口可能配置了一些可自定义的屏幕属性，因此，LocalWindowManager类的构造函数需要进一步地调整前面所获得的Display对象所描述的屏幕属性，以便可以适合当前正在处理的窗口使用。LocalWindowManager类的构造函数首先通过外部类Window的成员变量mContext的成员函数getResources来获得一个Resources对象，接着再调用这个Resources对象的成员函数getDefaultDisplay来调整前面所获得的Display对象所描述的屏幕属性。最终调整完成的Display对象就保存在LocalWindowManager类的成员变量mDefaultDisplay中。</p><p>&nbsp;&nbsp; &nbsp; &nbsp; 从前面的Step 4可以知道，类Window的成员变量mContext描述的是与当前窗口所关联的一个Activity组件。Activity类的成员函数getResources是从父类ContextWrapper继续下来的，它实现在文件frameworks/base/core/java/android/content/ContextWrapper.java中，如下所示：</p><p></p><pre code_snippet_id="129045" snippet_file_name="blog_20131226_11_169795"  code_snippet_id="129045" snippet_file_name="blog_20131226_11_169795" name="code" class="java">public class ContextWrapper extends Context {
    Context mBase;
    ......

    @Override
    public Resources getResources()
    {
        return mBase.getResources();
    }

    ......
}</pre>&nbsp;&nbsp; &nbsp; &nbsp; 从前面<a target=_blank target="_blank" href="http://blog.csdn.net/luoshengyang/article/details/8201936">Android应用程序窗口（Activity）的运行上下文环境（Context）的创建过程分析</a>一文可以知道，ContextWrapper类的成员变量mBase指向的是一个ContextImpl对象，用来描述一个Activity组件的运行上下文环境。通过调用这个ContextImpl对象的成员函数getResources，就可以获得与一个Resources对象，而通过这个Resources对象，就可以访问一个Activity组件的资源信息，从而可以获得它所配置的屏幕属性。<p></p><p>&nbsp;&nbsp; &nbsp; &nbsp; 至此，我们就分析完成一个Activity组件所关联的应用程序窗口对象的创建过程了。从分析的过程可以知道：</p><p>&nbsp;&nbsp; &nbsp; &nbsp;1. 一个Activity组件所关联的应用程序窗口对象的类型为PhoneWindow。</p><p>&nbsp;&nbsp; &nbsp; &nbsp;2. 这个类型为PhoneWindow的应用程序窗口是通过一个类型为LocalWindowManager的本地窗口管理器来维护的。</p><p>&nbsp;&nbsp; &nbsp; &nbsp;3. 这个类型为LocalWindowManager的本地窗口管理器又是通过一个类型为WindowManagerImpl的窗口管理器来维护应用程序窗口的。</p><p>&nbsp;&nbsp; &nbsp; &nbsp;4.&nbsp;这个类型为PhoneWindow的应用程序窗口内部有一个类型为DecorView的视图对象，这个视图对象才是真正用来描述一个Activity组件的UI的。<br /></p><p>&nbsp;&nbsp; &nbsp; &nbsp;在接下来的一篇文章中，我们将继续分析应用程序窗口内部的视图对象的创建过程，敬请关注！</p><p style="text-align: center;"><strong><span style="font-size:14px;color:#cc0000;">老罗的新浪微博：<a target=_blank target="_blank" href="http://weibo.com/shengyangluo" style="text-align: center;">http://weibo.com/shengyangluo</a>，欢迎关注！</span></strong></p>
</div>



<!-- Baidu Button BEGIN -->
<div id="bdshare" class="bdshare_t bds_tools get-codes-bdshare" style="float: right;">
<a class="bds_qzone"></a>
<a class="bds_tsina"></a>
<a class="bds_tqq"></a>
<a class="bds_renren"></a>
<a class="bds_t163"></a>
<span class="bds_more">更多</span>
<a class="shareCount"></a>
</div>
<!-- Baidu Button END -->


<!--192.168.100.34-->
<div class="article_next_prev">
            <li class="prev_article"><span>上一篇：</span><a href="/luoshengyang/article/details/8201936" onclick="_gaq.push(['_trackEvent','function', 'onclick', 'blog_articles_shangyipian'])">Android应用程序窗口（Activity）的运行上下文环境（Context）的创建过程分析</a></li>
            <li class="next_article"><span>下一篇：</span><a href="/luoshengyang/article/details/8245546" onclick="_gaq.push(['_trackEvent','function', 'onclick', 'blog_articles_xiayipian'])">Android应用程序窗口（Activity）的视图对象（View）的创建过程分析</a></li>
</div>

<!-- Baidu Button BEGIN -->
<script type="text/javascript" id="bdshare_js" data="type=tools&amp;uid=1536434" ></script>
<script type="text/javascript" id="bdshell_js"></script>
<script type="text/javascript">
    document.getElementById("bdshell_js").src = "http://bdimg.share.baidu.com/static/js/shell_v2.js?cdnversion=" + Math.ceil(new Date()/3600000)
</script>
<!-- Baidu Button END -->

        <div id="digg" ArticleId="8223770">
            <dl id="btnDigg" class="digg digg_disable">
                <dt onclick="_gaq.push(['_trackEvent','function', 'onclick', 'blog_articles_ding'])">顶</dt>
                <dd>16</dd>
            </dl>
            <dl id="btnBury" class="digg digg_disable">
                <dt onclick="_gaq.push(['_trackEvent','function', 'onclick', 'blog_articles_cai'])">踩</dt>
                <dd>1</dd>
            </dl>
        </div>
</div>
      <dl class="blog-associat-tag">
        <dt>相关主题推荐</dt>
        <dd>
                <a href="http://www.csdn.net/tag/android应用" target="_blank">android应用</a> 
                <a href="http://www.csdn.net/tag/对象" target="_blank">对象</a> 
                <a href="http://www.csdn.net/tag/新浪微博" target="_blank">新浪微博</a> 
                <a href="http://www.csdn.net/tag/application" target="_blank">application</a> 
                <a href="http://www.csdn.net/tag/interface" target="_blank">interface</a> 
        </dd>
    </dl> 
    <dl class="blog-ass-articl">
        <dt>相关博文推荐</dt>
            <dd>
                <a href="http://blog.csdn.net/ttdevs/article/details/21156543" title="android网络开源框架volley(四)——谈谈图片加载续——九张图片相册的展示(微信微博等)" target="_blank">android网络开源框架volley(...</a></dd>
            <dd>
                <a href="http://blog.csdn.net/misakahina/article/details/21161003" title="传智播客WPF视频 第一节" target="_blank">传智播客WPF视频 第一节</a></dd>
            <dd>
                <a href="http://blog.csdn.net/u013575027/article/details/21160663" title="对HTML DOM的理解" target="_blank">对HTML DOM的理解</a></dd>
            <dd>
                <a href="http://blog.csdn.net/u014077333/article/details/21160461" title="Win8.1升级预览版13大特性：默认启动传统桌面" target="_blank">Win8.1升级预览版13大特性：默认启...</a></dd>
            <dd>
                <a href="http://blog.csdn.net/HosiHui/article/details/21160197" title="html之object标签的classid收集" target="_blank">html之object标签的classi...</a></dd>
            <dd>
                <a href="http://blog.csdn.net/u013866576/article/details/21139023" title="swing application 实现：输入一串数字，查找指定数字，并输出位置，若有出现多次，所有位置都要输出。" target="_blank">swing application 实现...</a></dd>
            <dd>
                <a href="http://blog.csdn.net/ykcmi/article/details/21127485" title="Intent 传值和 Bundle传值的区别" target="_blank">Intent 传值和 Bundle传值的...</a></dd>
            <dd>
                <a href="http://blog.csdn.net/zslefour/article/details/21111851" title="VB.NET关于接口" target="_blank">VB.NET关于接口</a></dd>
    </dl>

    <div id="ad_cen">
        <script type="text/javascript">            BAIDU_CLB_SLOT_ID = "117306";</script>
        <script type="text/javascript" src="http://cbjs.baidu.com/js/o.js"></script>
    </div>
    <script type="text/javascript">
        //new Ad(4, 'ad_cen');
    </script>
<div id="comment_title" class="panel_head">
    查看评论<a name="comments"></a></div>
<div id="comment_list">
</div>
<div id="comment_bar">
</div>
<div id="comment_form">
</div>
<div class="announce">
    * 以上用户言论只代表其个人观点，不代表CSDN网站的观点或立场<a name="reply"></a><a name="quote"></a></div>
<script type="text/javascript">
    var fileName = '8223770';
    var commentscount = 21;
    var islock = false
</script>
<script type="text/javascript" src="http://static.blog.csdn.net/scripts/comment.js"></script>
    <div id="ad_bot">
    </div>
    <script type="text/javascript">
    new Ad(5, 'ad_bot');
    </script>
<div id="report_dialog">
</div>
<div id="d-top" style="display: none;">
    <a id="d-top-a" href="#" title="回到顶部" onclick="_gaq.push(['_trackEvent','function', 'onclick', 'blog_articles_huidaodingbu'])">
        <img src="http://static.blog.csdn.net/images/top.png" alt="TOP" /></a>
</div>
<script type="text/javascript">
    $(function ()
    {
        var d_top = $('#d-top');
        document.onscroll = function ()
        {
            var scrTop = (document.body.scrollTop || document.documentElement.scrollTop);
            if (scrTop > 500)
            {
                d_top.show();
            } else
            {
                d_top.hide();
            }
        }
        $('#d-top-a').click(function ()
        {
            scrollTo(0, 0);
            this.blur();
            return false;
        });
    });
  
</script>
<style type="text/css">
    .tag_list
    {
        background: none repeat scroll 0 0 #FFFFFF;
        border: 1px solid #D7CBC1;
        color: #000000;
        font-size: 12px;
        line-height: 20px;
        list-style: none outside none;
        margin: 10px 2% 0 1%;
        padding: 1px;
    }
    .tag_list h5
    {
        background: none repeat scroll 0 0 #E0DBD3;
        color: #47381C;
        font-size: 12px;
        height: 24px;
        line-height: 24px;
        padding: 0 5px;
        margin: 0;
    }
    .tag_list h5 a
    {
        color: #47381C;
    }
    .classify
    {
        margin: 10px 0;
        padding: 4px 12px 8px;
    }
    .classify a
    {
        margin-right: 20px;
        white-space: nowrap;
    }
</style>
<div class="tag_list">
    <h5>
        <a href="http://www.csdn.net/tag/" target="_blank">核心技术类目</a></h5>
    <div class="classify">
<a title="全部主题" href="http://www.csdn.net/tag" target="_blank" onclick="LogClickCount(this,336);">全部主题</a>
<a title="Java" href="http://www.csdn.net/tag/Java" target="_blank" onclick="LogClickCount(this,336);">Java</a>
<a title="VPN" href="http://www.csdn.net/tag/vpn" target="_blank" onclick="LogClickCount(this,336);">VPN</a>
<a title="Android" href="http://www.csdn.net/tag/android" target="_blank" onclick="LogClickCount(this,336);">Android</a>
<a title="iOS" href="http://www.csdn.net/tag/ios" target="_blank" onclick="LogClickCount(this,336);">iOS</a>
<a title="ERP" href="http://www.csdn.net/tag/erp" target="_blank" onclick="LogClickCount(this,336);">ERP</a>
<a title="IE10" href="http://www.csdn.net/tag/ie10" target="_blank" onclick="LogClickCount(this,336);">IE10</a>
<a title="Eclipse" href="http://www.csdn.net/tag/eclipse" target="_blank" onclick="LogClickCount(this,336);">Eclipse</a>
<a title="CRM" href="http://www.csdn.net/tag/crm" target="_blank" onclick="LogClickCount(this,336);">CRM</a>
<a title="JavaScript" href="http://www.csdn.net/tag/javascript" target="_blank" onclick="LogClickCount(this,336);">JavaScript</a>
<a title="Ubuntu" href="http://www.csdn.net/tag/ubuntu" target="_blank" onclick="LogClickCount(this,336);">Ubuntu</a>
<a title="NFC" href="http://www.csdn.net/tag/nfc" target="_blank" onclick="LogClickCount(this,336);">NFC</a>
<a title="WAP" href="http://www.csdn.net/tag/wap" target="_blank" onclick="LogClickCount(this,336);">WAP</a>
<a title="jQuery" href="http://www.csdn.net/tag/jquery" target="_blank" onclick="LogClickCount(this,336);">jQuery</a>
<a title="数据库" href="http://www.csdn.net/tag/数据库" target="_blank" onclick="LogClickCount(this,336);">数据库</a>
<a title="BI" href="http://www.csdn.net/tag/bi" target="_blank" onclick="LogClickCount(this,336);">BI</a>
<a title="HTML5" href="http://www.csdn.net/tag/html5" target="_blank" onclick="LogClickCount(this,336);">HTML5</a>
<a title="Spring" href="http://www.csdn.net/tag/spring" target="_blank" onclick="LogClickCount(this,336);">Spring</a>
<a title="Apache" href="http://www.csdn.net/tag/apache" target="_blank" onclick="LogClickCount(this,336);">Apache</a>
<a title="Hadoop" href="http://www.csdn.net/tag/hadoop" target="_blank" onclick="LogClickCount(this,336);">Hadoop</a>
<a title=".NET" href="http://www.csdn.net/tag/.net" target="_blank" onclick="LogClickCount(this,336);">.NET</a>
<a title="API" href="http://www.csdn.net/tag/api" target="_blank" onclick="LogClickCount(this,336);">API</a>
<a title="HTML" href="http://www.csdn.net/tag/html" target="_blank" onclick="LogClickCount(this,336);">HTML</a>
<a title="SDK" href="http://www.csdn.net/tag/sdk" target="_blank" onclick="LogClickCount(this,336);">SDK</a>
<a title="IIS" href="http://www.csdn.net/tag/iis" target="_blank" onclick="LogClickCount(this,336);">IIS</a>
<a title="Fedora" href="http://www.csdn.net/tag/fedora" target="_blank" onclick="LogClickCount(this,336);">Fedora</a>
<a title="XML" href="http://www.csdn.net/tag/xml" target="_blank" onclick="LogClickCount(this,336);">XML</a>
<a title="LBS" href="http://www.csdn.net/tag/lbs" target="_blank" onclick="LogClickCount(this,336);">LBS</a>
<a title="Unity" href="http://www.csdn.net/tag/unity" target="_blank" onclick="LogClickCount(this,336);">Unity</a>
<a title="Splashtop" href="http://www.csdn.net/tag/splashtop" target="_blank" onclick="LogClickCount(this,336);">Splashtop</a>
<a title="UML" href="http://www.csdn.net/tag/uml" target="_blank" onclick="LogClickCount(this,336);">UML</a>
<a title="components" href="http://www.csdn.net/tag/components" target="_blank" onclick="LogClickCount(this,336);">components</a>
<a title="Windows Mobile" href="http://www.csdn.net/tag/windowsmobile" target="_blank" onclick="LogClickCount(this,336);">Windows Mobile</a>
<a title="Rails" href="http://www.csdn.net/tag/rails" target="_blank" onclick="LogClickCount(this,336);">Rails</a>
<a title="QEMU" href="http://www.csdn.net/tag/qemu" target="_blank" onclick="LogClickCount(this,336);">QEMU</a>
<a title="KDE" href="http://www.csdn.net/tag/kde" target="_blank" onclick="LogClickCount(this,336);">KDE</a>
<a title="Cassandra" href="http://www.csdn.net/tag/cassandra" target="_blank" onclick="LogClickCount(this,336);">Cassandra</a>
<a title="CloudStack" href="http://www.csdn.net/tag/cloudstack" target="_blank" onclick="LogClickCount(this,336);">CloudStack</a>
<a title="FTC" href="http://www.csdn.net/tag/ftc" target="_blank" onclick="LogClickCount(this,336);">FTC</a>
<a title="coremail" href="http://www.csdn.net/tag/coremail" target="_blank" onclick="LogClickCount(this,336);">coremail</a>
<a title="OPhone " href="http://www.csdn.net/tag/ophone " target="_blank" onclick="LogClickCount(this,336);">OPhone </a>
<a title="CouchBase" href="http://www.csdn.net/tag/couchbase" target="_blank" onclick="LogClickCount(this,336);">CouchBase</a>
<a title="云计算" href="http://www.csdn.net/tag/云计算" target="_blank" onclick="LogClickCount(this,336);">云计算</a>
<a title="iOS6" href="http://www.csdn.net/tag/iOS6" target="_blank" onclick="LogClickCount(this,336);">iOS6</a>
<a title="Rackspace " href="http://www.csdn.net/tag/rackspace " target="_blank" onclick="LogClickCount(this,336);">Rackspace </a>
<a title="Web App" href="http://www.csdn.net/tag/webapp" target="_blank" onclick="LogClickCount(this,336);">Web App</a>
<a title="SpringSide" href="http://www.csdn.net/tag/springside" target="_blank" onclick="LogClickCount(this,336);">SpringSide</a>
<a title="Maemo" href="http://www.csdn.net/tag/maemo" target="_blank" onclick="LogClickCount(this,336);">Maemo</a>
<a title="Compuware" href="http://www.csdn.net/tag/compuware" target="_blank" onclick="LogClickCount(this,336);">Compuware</a>
<a title="大数据" href="http://www.csdn.net/tag/大数据" target="_blank" onclick="LogClickCount(this,336);">大数据</a>
<a title="aptech" href="http://www.csdn.net/tag/aptech" target="_blank" onclick="LogClickCount(this,336);">aptech</a>
<a title="Perl" href="http://www.csdn.net/tag/perl" target="_blank" onclick="LogClickCount(this,336);">Perl</a>
<a title="Tornado" href="http://www.csdn.net/tag/tornado" target="_blank" onclick="LogClickCount(this,336);">Tornado</a>
<a title="Ruby" href="http://www.csdn.net/tag/ruby" target="_blank" onclick="LogClickCount(this,336);">Ruby</a>
<a title="Hibernate" href="http://www.csdn.net/hibernate" target="_blank" onclick="LogClickCount(this,336);">Hibernate</a>
<a title="ThinkPHP" href="http://www.csdn.net/tag/thinkphp" target="_blank" onclick="LogClickCount(this,336);">ThinkPHP</a>
<a title="Spark" href="http://www.csdn.net/tag/spark" target="_blank" onclick="LogClickCount(this,336);">Spark</a>
<a title="HBase" href="http://www.csdn.net/tag/hbase" target="_blank" onclick="LogClickCount(this,336);">HBase</a>
<a title="Pure" href="http://www.csdn.net/tag/pure" target="_blank" onclick="LogClickCount(this,336);">Pure</a>
<a title="Solr" href="http://www.csdn.net/tag/solr" target="_blank" onclick="LogClickCount(this,336);">Solr</a>
<a title="Angular" href="http://www.csdn.net/tag/angular" target="_blank" onclick="LogClickCount(this,336);">Angular</a>
<a title="Cloud Foundry" href="http://www.csdn.net/tag/cloudfoundry" target="_blank" onclick="LogClickCount(this,336);">Cloud Foundry</a>
<a title="Redis" href="http://www.csdn.net/tag/redis" target="_blank" onclick="LogClickCount(this,336);">Redis</a>
<a title="Scala" href="http://www.csdn.net/tag/scala" target="_blank" onclick="LogClickCount(this,336);">Scala</a>
<a title="Django" href="http://www.csdn.net/tag/django" target="_blank" onclick="LogClickCount(this,336);">Django</a>
<a title="Bootstrap" href="http://www.csdn.net/tag/bootstrap" target="_blank" onclick="LogClickCount(this,336);">Bootstrap</a>
    </div>
</div>

                    <div class="clear">
                    </div>
                </div>
            </div>
            <div id="side">
    <div class="side">
<div id="panel_Profile" class="panel">
<ul class="panel_head"><span>个人资料</span></ul>
<ul class="panel_body profile">
<div id="blog_userface">
    <a href="http://my.csdn.net/Luoshengyang" target="_blank">
    <img src="http://avatar.csdn.net/5/6/E/1_luoshengyang.jpg" title="访问我的空间" style="max-width:90%"/>
    </a>
    <br />
    <span><a href="http://my.csdn.net/Luoshengyang" class="user_name" target="_blank">Luoshengyang</a></span>
</div>
<div class="interact">
<a href="javascript:void(0);" class="attent" id="span_add_follow" title="[加关注]" onclick="_gaq.push(['_trackEvent','function', 'onclick', 'blog_articles_guanzhu'])"></a>
<a href="javascript:void(0);" class="letter" onclick="loginto(1)" title="[发私信]" onclick="_gaq.push(['_trackEvent','function', 'onclick', 'blog_articles_sixin'])"></a>
</div>
<div id="blog_medal">
        <div class="ico_expert" title="CSDN认证专家"></div>
</div>
<ul id="blog_rank">
    <li>访问：<span>3162521次</span></li>
    <li>积分：<span>16459分</span></li>
    <li>排名：<span>第129名</span></li>
</ul>
<ul id="blog_statistics">
    <li>原创：<span>100篇</span></li>
    <li>转载：<span>0篇</span></li>
    <li>译文：<span>0篇</span></li>
    <li>评论：<span>5215条</span></li>
</ul>
</ul>
</div>


<div id="custom_column_6567056" class="panel">
<ul class="panel_head"><span>博客公告</span></ul>
<ul class="panel_body">
<b><font color="red" size="2">本博客所有文章均为原创，欢迎交流，欢迎转载；转载请勿篡改内容，并且注明出处，禁止用于商业目的，谢谢！</font></b>
</ul>
</div><div id="custom_column_21664874" class="panel">
<ul class="panel_head"><span>图书信息</span></ul>
<ul class="panel_body">
<font color="red"><b>书名：</b></font>
<p>《Android系统源代码情景分析》</p>

<p><a href="http://wenku.it168.com/d_000574719.shtml" target="_blank">试读请点击</a></p>

<p><font color="red"><b>出版社：</b></font></p>
<p>电子工业出版社</p>

<p><font color="red"><b>网店：</b></font></p>

<p>1. <a href="http://product.dangdang.com/product.aspx?product_id=22884086" target="_blank">当当网（满100减20，满200减50）</a></p><p></p>

<p>2. <a href="http://book.360buy.com/11104739.html" target="_blank">京东网（满99减20）</a></p><p></p>

<p>3. <a href="http://www.amazon.cn/Android%E7%B3%BB%E7%BB%9F%E6%BA%90%E4%BB%A3%E7%A0%81%E6%83%85%E6%99%AF%E5%88%86%E6%9E%90-%E7%BD%97%E5%8D%87%E9%98%B3/dp/B009OLU8EE" target="_blank">亚马逊网（满100减20，满200减50）</a></p><p></p>

<p>4. <a href="http://product.china-pub.com/3684413" target="_blank">互动出版网</a></p><p></p>

<p>5. <a href="http://www.suning.com/emall/prd_10052_22001_-7_3435777_.html" target="_blank">苏宁易购网</a></p><p></p>

<p><a href="http://s.etao.com/search?spm=1002.8.1.1386.g76Rk3&amp;q=Android%CF%B5%CD%B3%D4%B4%B4%FA%C2%EB%C7%E9%BE%B0%B7%D6%CE%F6&amp;style=list&amp;initiative_id=etao_20121011&amp;pn=1&amp;sort=sale-desc" target="_blank">比一比谁更实惠</a></p>

<p><font color="red"><b>号外：</b></font></p>

<p>本书繁体版已经成功输出到台湾</p>

<p></p>
</ul>
</div><div id="custom_column_21603386" class="panel">
<ul class="panel_head"><span>联系方式</span></ul>
<ul class="panel_body">
<font color="red"><b>新浪微博：</b></font>
<p><a href="http://weibo.com/shengyangluo" target="_blank"><font color="red"><b>http://weibo.com/shengyangluo</b></font></a></p><p></p>

<font color="red"><b>QQ交流群：</b></font>
<p><b><font color="red">130112760</font></b>（1000人群，已满）</p>
<p><b><font color="red">248749286</font></b>（1000人群，已满）</p>
<p><b><font color="red">204155322</font></b>（500人群，未满）</p>
<p><b><font color="red">278558417</font></b>（500人群，已满）</p>
<p><b><font color="red">303165655</font></b>（500人群，已满）</p>
<p>PS：请勿同时加入多个群，一经发现，永久封号，谢谢！</p>
</ul>
</div><div id="panel_Category" class="panel">
    <ul class="panel_head"><span>博客专栏</span></ul>
    <ul class="panel_body" id="sp_column">
    <table cellpadding="0" cellspacing="0"><tr>
    <td style="padding:10px 10px 0 0;">
    <a href="http://blog.csdn.net/column/details/androidluo.html" target="_blank"><img src="http://avatar.csdn.net/blogpic/20111107095438958.jpg" style="width:75px;height:75px;" /></a>
    </td>
    <td style="padding:10px 0; vertical-align:top;">
    <a href="http://blog.csdn.net/column/details/androidluo.html" target="_blank">老罗的Android之旅</a>
    <p>文章：100篇</p>
    <span>阅读：3166324</span>
    </td>
    </tr></table>
    </ul>
</div><div id="hotarticls" class="panel">
<ul class="panel_head"><span>阅读排行</span></ul>
<ul class="panel_body itemlist">
<li>
<a href="/luoshengyang/article/details/6559955" title="在Ubuntu上下载、编译和安装Android最新源代码">在Ubuntu上下载、编译和安装Android最新源代码</a><span>(109394)</span>
</li>
<li>
<a href="/luoshengyang/article/details/6618363" title="Android进程间通信（IPC）机制Binder简要介绍和学习计划">Android进程间通信（IPC）机制Binder简要介绍和学习计划</a><span>(95304)</span>
</li>
<li>
<a href="/luoshengyang/article/details/6689748" title="Android应用程序启动过程源代码分析">Android应用程序启动过程源代码分析</a><span>(80837)</span>
</li>
<li>
<a href="/luoshengyang/article/details/6568411" title="在Ubuntu上为Android系统编写Linux内核驱动程序">在Ubuntu上为Android系统编写Linux内核驱动程序</a><span>(78601)</span>
</li>
<li>
<a href="/luoshengyang/article/details/8923485" title="那两年炼就的Android内功修养">那两年炼就的Android内功修养</a><span>(76636)</span>
</li>
<li>
<a href="/luoshengyang/article/details/6567257" title="Android硬件抽象层（HAL）概要介绍和学习计划">Android硬件抽象层（HAL）概要介绍和学习计划</a><span>(72505)</span>
</li>
<li>
<a href="/luoshengyang/article/details/6564592" title="在Ubuntu上下载、编译和安装Android最新内核源代码（Linux Kernel）">在Ubuntu上下载、编译和安装Android最新内核源代码（Linux Kernel）</a><span>(66693)</span>
</li>
<li>
<a href="/luoshengyang/article/details/6557518" title="Android学习启动篇">Android学习启动篇</a><span>(59032)</span>
</li>
<li>
<a href="/luoshengyang/article/details/6566662" title="如何单独编译Android源代码中的模块">如何单独编译Android源代码中的模块</a><span>(57994)</span>
</li>
<li>
<a href="/luoshengyang/article/details/6575988" title="在Ubuntu为Android硬件抽象层（HAL）模块编写JNI方法提供Java访问硬件服务接口">在Ubuntu为Android硬件抽象层（HAL）模块编写JNI方法提供Java访问硬件服务接口</a><span>(56721)</span>
</li>
</ul>
</div>
<div id="hotarticls2" class="panel">
<ul class="panel_head"><span>评论排行</span></ul>
<ul class="panel_body itemlist">
<li>
<a href="/luoshengyang/article/details/6689748" title="Android应用程序启动过程源代码分析">Android应用程序启动过程源代码分析</a><span>(322)</span>
</li>
<li>
<a href="/luoshengyang/article/details/6559955" title="在Ubuntu上下载、编译和安装Android最新源代码">在Ubuntu上下载、编译和安装Android最新源代码</a><span>(238)</span>
</li>
<li>
<a href="/luoshengyang/article/details/8116866" title="《Android系统源代码情景分析》一书勘误">《Android系统源代码情景分析》一书勘误</a><span>(208)</span>
</li>
<li>
<a href="/luoshengyang/article/details/6882903" title="Android应用程序键盘（Keyboard）消息处理机制分析">Android应用程序键盘（Keyboard）消息处理机制分析</a><span>(182)</span>
</li>
<li>
<a href="/luoshengyang/article/details/8923485" title="那两年炼就的Android内功修养">那两年炼就的Android内功修养</a><span>(181)</span>
</li>
<li>
<a href="/luoshengyang/article/details/6580267" title="在Ubuntu上为Android系统内置Java应用程序测试Application Frameworks层的硬件服务">在Ubuntu上为Android系统内置Java应用程序测试Application Frameworks层的硬件服务</a><span>(170)</span>
</li>
<li>
<a href="/luoshengyang/article/details/7409491" title="Android博客文章整理">Android博客文章整理</a><span>(167)</span>
</li>
<li>
<a href="/luoshengyang/article/details/6568411" title="在Ubuntu上为Android系统编写Linux内核驱动程序">在Ubuntu上为Android系统编写Linux内核驱动程序</a><span>(151)</span>
</li>
<li>
<a href="/luoshengyang/article/details/8452527" title="2012年的Android之旅：梦想、学习、坚持、自信、淡定">2012年的Android之旅：梦想、学习、坚持、自信、淡定</a><span>(139)</span>
</li>
<li>
<a href="/luoshengyang/article/details/6564592" title="在Ubuntu上下载、编译和安装Android最新内核源代码（Linux Kernel）">在Ubuntu上下载、编译和安装Android最新内核源代码（Linux Kernel）</a><span>(136)</span>
</li>
</ul>
</div>
<div id="newcomments" class="panel">
<ul class="panel_head"><span>最新评论</span></ul>
<ul class="panel_body itemlist">
    <li>
    <a href="/Luoshengyang/article/details/6786239#comments">Android系统的智能指针（轻量级指针、强指针和弱指针）的实现原理分析</a>
    <p style="margin:0px;"><a href="/ssikyou" class="user_name">ssikyou</a>:
顶老罗！补充，多调用的addWeakRef在4.4里已经没有了，OBJECT_LIFETIME_FO...
    </p>
    </li>
    <li>
    <a href="/Luoshengyang/article/details/6817933#comments">Android应用程序消息处理机制（Looper、Handler）分析</a>
    <p style="margin:0px;"><a href="/yuanshisenlin123" class="user_name">yuanshisenlin123</a>:
做了将近两年的Android应用开发，表示没看懂，看来还得多多学习哇！
    </p>
    </li>
    <li>
    <a href="/Luoshengyang/article/details/19023609#comments">Android源代码编译命令m/mm/mmm/make分析</a>
    <p style="margin:0px;"><a href="/thinkinwm" class="user_name">thinkinwm</a>:
好文章！
    </p>
    </li>
    <li>
    <a href="/Luoshengyang/article/details/6568411#comments">在Ubuntu上为Android系统编写Linux内核驱动程序</a>
    <p style="margin:0px;"><a href="/HuiyuYang_fish" class="user_name">HuiyuYang_fish</a>:
期待实验~
    </p>
    </li>
    <li>
    <a href="/Luoshengyang/article/details/6557518#comments">Android学习启动篇</a>
    <p style="margin:0px;"><a href="/HuiyuYang_fish" class="user_name">HuiyuYang_fish</a>:
貌似我也要开始android的初步涉猎了~
    </p>
    </li>
    <li>
    <a href="/Luoshengyang/article/details/12957169#comments">《老罗的Android之旅》导读PPT</a>
    <p style="margin:0px;"><a href="/mianju23" class="user_name">mianju23</a>:
牛人
    </p>
    </li>
    <li>
    <a href="/Luoshengyang/article/details/8452527#comments">2012年的Android之旅：梦想、学习、坚持、自信、淡定</a>
    <p style="margin:0px;"><a href="/wuxiaoming1733" class="user_name">wuxiaoming1733</a>:
顶楼主
    </p>
    </li>
    <li>
    <a href="/Luoshengyang/article/details/6737352#comments">Android应用程序注册广播接收器（registerReceiver）的过程分析</a>
    <p style="margin:0px;"><a href="/wuxiaoming1733" class="user_name">wuxiaoming1733</a>:
罗大神你好，我这边还没明白，怎么自己用代码，实现androidmanifest.xml里静态注册系统...
    </p>
    </li>
    <li>
    <a href="/Luoshengyang/article/details/6642463#comments">Android系统进程间通信Binder机制在应用程序框架层的Java接口源代码分析</a>
    <p style="margin:0px;"><a href="/zqz19891031" class="user_name">zqz19891031</a>:
博主您好，看了你的博客，收获颇多！有一个问题想请教：最近在看Android的Binder实现，看到B...
    </p>
    </li>
    <li>
    <a href="/Luoshengyang/article/details/8923485#comments">那两年炼就的Android内功修养</a>
    <p style="margin:0px;"><a href="/xin128888" class="user_name">xin128888</a>:
老罗，有问题能否指导下。目前我想学习驱动相关知识，但是不知道要看哪本入门书籍合适，目标主要是快速入门...
    </p>
    </li>
</ul>
</div>
    </div>
    <div class="clear">
    </div>
</div>

            <div class="clear">
            </div>
        </div>
        

<script type="text/javascript" src="http://static.blog.csdn.net/scripts/newblog.min.js"></script>
<script type="text/javascript" src="http://medal.blog.csdn.net/showblogmedal.ashx?blogid=1134701"></script>
<script type="text/javascript">
    document.write('<script type="text/javascript" src="http://csdnimg.cn/pubfooter/js/publib_footer.js?' + Math.floor(new Date() / 120000).toString(36) + '="></' + 'script>');
</script>
    <script type="text/javascript" src="http://passport.csdn.net/content/loginbox/login.js"></script>
<script type="text/javascript">document.write("<img src=http://counter.csdn.net/pv.aspx?id=24 border=0 width=0 height=0>");</script>
<script type="text/javascript" src="http://www.csdn.net/ui/scripts/Csdn/counter.js"></script>
<script type="text/javascript" src="http://ad.csdn.net/scripts/ad-blog.js"></script>
<script type="text/javascript" src="http://zz.csdn.net/js/count.js"></script>
<script type="text/javascript">
    $(function () {
        function __get_code_toolbar(snippet_id) {
            return $("<a href='https://code.csdn.net/snippets/"
                    + snippet_id
                    + "' target='_blank' title='在CODE上查看代码片' style='text-indent:0;'><img src='https://code.csdn.net/assets/CODE_ico.png' width=12 height=12 alt='在CODE上查看代码片' style='position:relative;top:1px;left:2px;'/></a>"
                    + "<a href='https://code.csdn.net/snippets/"
                    + snippet_id
                    + "/fork' target='_blank' title='派生到我的代码片'  style='text-indent:0;'><img src='https://code.csdn.net/assets/ico_fork.svg' width=12 height=12 alt='派生到我的代码片' style='position:relative;top:2px;left:2px;'/></a>");
        }
        
        $("[code_snippet_id]").each(function () {
            __s_id = $(this).attr("code_snippet_id");
            if (__s_id != null && __s_id != "" && __s_id != 0 && parseInt(__s_id) > 70020) {
                __code_tool = __get_code_toolbar(__s_id);
                $(this).prev().find(".tools").append(__code_tool);
            }
        });
    });
</script>

    </div>
      <!--new top-->
    
    <script id="csdn-toolbar-id" btnId="header_notice_num" wrapId="note1" count="5" subCount="5" type="text/javascript" src="http://static.csdn.net/public/common/toolbar/js/toolbar.js"></script>     <!--new top-->
</body>
</html>
